/**
* @namespace
* namespace - Contains all items related to bizobjs
* @meta-type namespace

*/
ksg.bizobj = {
	/**
	* @namespace
	* @meta-type Map
	* Map of all known bizObj types.
	*/
	bizObjTypes: { },

	/**
	* This should be the base prototype for all real bizobj types created
	* so that the standard functionality of a bizobj is available.
	* @class
	* @importance high
	*/
	BizObj: {
		/**
		* Will retrieve a value from the bizobj, and if not found or null is returned, the optional
		* defVal will be used if supplied.
		* <p>This method has deep name address support, which standard javascript obj["name.name"] 
		* does not.  Also, this method serves as a general point of entry for getting values out of a bizobj
		* and thus will support decorated bizobj values.</p>
		* @param {Object} obj The object to get the value from.  This does not actually need to be a BizObj based class - any javascript object will work.
		* @param {String} deepName The field name to get the value for, which can be a deep name address.
		* @param {Object} defVal optional - The default value to use if the resulting value is not found or null.
		* @returns {object} The value requested
		*/
		getValue: function(obj, deepName, defVal) {
			var child = defVal==null?null:defVal;
			if(obj && deepName) {
				var names = deepName.split('.');
				child = obj;
				for(var i = 0; i < names.length; i++)
					if(names[i] in child) {
						if((child = child[names[i]]) == null)
							break;
					}
					else
						return defVal;

			}
			return child;
		},
		
		/**
		* Will check to see if the given name is contained within the given object.
		* <p>This method has deep name address support, which standard javascript obj["name.name"] 
		* does not.</p>
		* @param {Object} obj the object to check if the given name exists in
		* @param {String} deepName the deep name address to check for
		* @returns {Boolean} 
		*/
		hasValue: function(obj, deepName) {
			var hasIt = true;
			if(obj && deepName) {
				var names = deepName.split('.');
				var child = obj;
				for(var i = 0; i < names.length; i++)
					if(names[i] in child)
						child = child[names[i]];
					else
						return false;
			}
			return hasIt;
		}
	},

	/**
	* While arrays of bizobjs can be used instead of BizObjList, this class provides 
	* methods that make using bizobjs easier.
	* so that the standard functionality of a bizobj is available.
	* @class
	* @importance high
	*/
	BizObjList: {
	}
};

$.extend(ksg.bizobj.bizObjTypes, {
	Article: {
		depthWidth: function (art) {
			return art.depth * 25;
		},
		calculatedShortTitle: function () {
			var d = this.data;
			return (d.shortTitle) ? d.shortTitle : d.title;
		}
	}
});

/**
* @class
* Provides a way to interate through a collection of bizobjs without having to
* maintain an index.  The cursor is an index into a list of bizobjs.
* @importance high
*/
ksg.bizobj.BizObjCursor = function(bizObjs) {
	this.bizObjs = bizObjs;
	this.pos = 0;
};

ksg.bizobj.BizObjCursor.prototype = {
	hasMoreThanOne: function() {
		return this.bizObjs.length > 1;
	},
	
	moveFirst:function() {
		this.pos = 0;
		return this.currentElement();
	},
	movePrev:function() {
		if(--this.pos < 0)
			this.pos = 0;
		return this.currentElement();
	},
	moveNext:function() {
		if(++this.pos >= this.bizObjs.length)
			if((this.pos = this.bizObjs.length-1) < 0)
				this.pos=0;
		return this.currentElement();
	},
	moveLast:function() {
		this.pos = this.bizObjs.length -1;
		if((this.pos = this.bizObjs.length-1) < 0)
			this.pos=0;
		return this.currentElement();
	},
	moveTo:function(pos) {
		if(pos >= 0 && pos < this.bizObjs.length)
			this.pos = pos;
		return this.currentElement();
	},
	isBOF:function() {
		return this.pos == 0;
	},
	isEOF:function(){
		var s = this.bizObjs.length-1;
		if(s<0)
			s==0;
		return this.pos == s;
	},
	currentElement:function() {
		if(this.pos >=0 && this.pos < this.bizObjs.length)
			return this.bizObjs[this.pos];
		return null;
	},
	pushForward: function(num) {
		num = new Number(num);
		var length = this.bizObjs.length;
		var start = this.pos, end = (num&&num>0)?this.pos+(num):length;
		if(end > length)
			end = length;
		this.pos = end;
		return this.bizObjs.slice(start,end);
	}
};

